---
sidebar_label: REST connectors
sidebar_position: 9
description: REST connectors for Hasura Actions
keywords:
  - hasura
  - docs
  - action
  - transforms
  - rest connectors
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import TOCInline from '@theme/TOCInline';
import Thumbnail from '@site/src/components/Thumbnail';

# REST Connectors for Actions

## Introduction

REST Connectors for Actions are used to integrate existing REST APIs to the GraphQL API without needing any middleware
or modifications to the upstream code.

REST Connectors modify the default HTTP request made by an action to adapt to your webhook's expected format by adding
suitable transforms.

:::info Note

General information about the templating used in REST Connectors can be found in the
[Kriti templating](/api-reference/kriti-templating.mdx) section of the documentation.

:::

:::tip Supported from

REST Connectors are supported in Hasura GraphQL Engine versions `v2.1.0` and above

:::

## Configuring REST Connectors

REST Connectors can be configured either when creating a new action or editing an existing one. See the transform
options [here](#action-transform-types):

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

Go to the `Actions` tab on the Console and create or modify an action. Scroll down to `Configure REST Connectors`
section:

<Thumbnail src="/img/actions/configure-rest-connectors.png" alt="Configure REST connectors for Actions" width="800px" />

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform](RequestTransformation]
field to the action:

```yaml {6-13}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
    timeout: 60
    request_transform:
      template_engine: Kriti
      method: POST
      content_type: application/json
      url: '{{$base_url}}/create_user'
      query_params:
        id: "{{$session_variables['x-hasura-user-id']}}"
      body: '{"username": {{$body.input.username}}}'
  comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```http {24-33}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
      "name":"create_user",
      "definition":{
        "kind":"synchronous",
        "arguments":[
            {
              "name":"username",
              "type":"String!"
            },
            {
              "name":"email",
              "type":"String!"
            }
        ],
        "output_type":"User",
        "handler":"https://action.my_app.com/create-user",
        "timeout":60,
        "request_transform": {
          "template_engine": "Kriti",
          "method": "POST",
          "url": "{{$base_url}}/create_user",
          "query_params": {
            "id": "{{$session_variables['x-hasura-user-id']}}"
          },
          "content_type": "application/json",
          "body": "{\"username\": {{$body.input.username}}}"
        }
      },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>

### Context Variables {#action-transform-context-variables}

You can use context variables in the transforms to achieve dynamic behavior for each request.

The context variables available in transforms are:

| Context variable   | Value                                      |
| ------------------ | ------------------------------------------ |
| $body              | Original body of action request            |
| $base_url          | Original configured webhook handler URL    |
| $session_variables | Session variables                          |
| $response.status   | HTTP response staus code from the webhook  |

In addition to these variables, the following functions are available in addition to the standard
[Basic Functions](/api-reference/kriti-templating.mdx#kriti-function-reference):

| Context variable           | Value                                                 |
| -------------------------- | ----------------------------------------------------- |
| `getSessionVariable(NAME)` | Look up a session variable by name (case-insensitive) |

#### Console sample context {#action-transforms-sample-context}

The Console allows you to preview your transforms while configuring them. To avoid exposing sensitive information on the
console UI the actual environment variables configured on the server are not resolved while displaying the previews.
Also any session variables used in the transform will not be available at the time of configuration.

Hence, the Console allows you to provide mock env variables and session variables to verify your transforms. If you
configure your transforms without providing the mock env/session variables you might see a UI validation error in the
preview sections.

**For example:** If your webhook handler is set as an env var as shown below then pass a mock value for that env var in
the sample context:

<Thumbnail src="/img/actions/transform-sample-context-0.png" alt="Console action webhook handler" width="650px" />

You can enter the mock env/session variables under `Configure REST Connectors > Sample Context`:

<Thumbnail src="/img/actions/transform-sample-context-1.png" alt="Add generic sample context" width="800px" />

:::info Note

As the sample context is only used for previews, you can still configure the transforms on the Console without setting
any sample context.

:::

## Types of transforms {#action-transform-types}

REST Connectors allow you to add different transforms to the default HTTP request. You can also use
[context variables](#action-transform-context-variables) in the transforms to achieve dynamic behavior for each request.

You can transform your:

<TOCInline toc={toc} filterTOC={'action-transform-types'} />

### Request Method

You can change the request method to adapt to your API's expected format.

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Request Options Transform`:

<Thumbnail
  src="/img/actions/transform-method.png"
  alt="Change request method"
  width="800px"
/>
</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform][requesttransformation]
field to the action:

```yaml {8}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  request_transform:
    template_engine: Kriti
    method: POST
    content_type: application/json
    url: '{{$base_url}}/create_user'
    query_params:
      id: '{{$session_variables[''x-hasura-user-id'']}}'
    body: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```http {26}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "request_transform": {
        "template_engine": "Kriti",
        "method": "POST",
        "url": "{{$base_url}}/create_user",
        "query_params": {
          "id": "{{$session_variables['x-hasura-user-id']}}"
        },
        "content_type": "application/json",
        "body": "{\"username\": {{$body.input.username}}}"
      }
    },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>

### Request URL

The Request URL template allows you to configure the exact API endpoint to call.

You can use the [context variables](#action-transform-context-variables) to construct the final URL.

- [Request URL with Query Parmeters (as key-value pairs)](#request-url-with-query-parmeters-as-key-value-pairs)
- [Request URL with Query Parmeters (as raw string)](#request-url-with-query-parmeters-as-raw-string)

##### Request URL with Query Parmeters (as key-value pairs)

You can provide `Key-Value` type query params to add to the URL.

You can also use the [Kriti templating language](/api-reference/kriti-templating.mdx) to construct any string values here.

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Request Options Transform`:
<Thumbnail src="/img/actions/transform-key-value-url.png" alt="Change request URL" width="800px" />

The value of the final url should be reflected in the `Preview` section given all required
[sample context](#action-transforms-sample-context) is set.

Hit `Save Action` to apply your changes.

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform][requesttransformation]
field to the action:

```yaml {10-12}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  request_transform:
    template_engine: Kriti
    method: POST
    content_type: application/json
    url: '{{$base_url}}/create_user'
    query_params:
      id: '{{$session_variables[''x-hasura-user-id'']}}'
    body: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```HTTP {27-30}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "request_transform": {
        "template_engine": "Kriti",
        "method": "POST",
        "url": "{{$base_url}}/create_user",
        "query_params": {
          "id": "{{$session_variables['x-hasura-user-id']}}"
        },
        "content_type": "application/json",
        "body": "{\"username\": {{$body.input.username}}}"
      }
    },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>

##### Request URL with Query Parmeters (as raw string)

You can provide `string` type query params to add to the URL.

You can also use the [Kriti templating language](/api-reference/kriti-templating.mdx) to construct any string values here.

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Request Options Transform`:
<Thumbnail src="/img/actions/transform-url-string-url.png" alt="Change request URL" width="800px" />

The value of the final url should be reflected in the `Preview` section given all required
[sample context](#action-transforms-sample-context) is set.

Hit `Save Action` to apply your changes.

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform][requesttransformation]
field to the action:

```yaml {10-11}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  request_transform:
    template_engine: Kriti
    method: POST
    content_type: application/json
    url: '{{$base_url}}/create_user'
    query_params: "{{concat(["userId=", $session_variables["x-hasura-user-id"]])}}"
    body: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```HTTP {27-28}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "request_transform": {
        "template_engine": "Kriti",
        "method": "POST",
        "url": "{{$base_url}}/create_user",
        "query_params": "{{concat(["userId=", $session_variables["x-hasura-user-id"]])}}"
        "content_type": "application/json",
        "body": "{\"username\": {{$body.input.username}}}"
      }
    },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>



:::info escapeUri

Note that you must use the `escapeUri` function to urlencode templated values. For example, if you have to use session
variables in the URL and those may contain non-ASCII values, then you should provide the template URL as
`{{$base_url}}/{{escapeUri($session_variables['x-hasura-user-id'])}}`

:::

:::info Optional query params

Query params with key/value pairs which evaluate to `null` are ignored by Hasura while performing the HTTP API call.
Hasura considers such query params optional.

For example, consider a query param value with template `{{$session_variables?['x-hasura-user-id']}}`. If the variable
`x-hasura-user-id` is absent in the session variables, then the query param will be omitted from the HTTP API call.

:::

### Request Body

You can generate a custom request body by configuring a template to transform the default payload to a custom payload.
Request body could be provided using the `body` field as an [object](/api-reference/syntax-defs.mdx/#bodytransform),
which additionally gives the ability to disable request body, transform request body to `application/json`, or transform
request body to `x_www_form_urlencoded` formats.

- [Disabling Request Body](#disabling-request-body)
- [Request Body with application/json format](#request-body-with-applicationjson-format)
- [Request Body with x_www_form_urlencoded format](#request-body-with-x_www_form_urlencoded-format)

##### Disabling Request Body

If you are using a `GET` request, you might want to not send any request body, and additionally not send a
`content-type` header to the webhook. You can do that using the disable body feature.

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Request Options Transform`, and convert the `Request Method`
as `GET`.  
Then click on `Add Payload Transform`, disable the payload body by using the dropdown next to the
`Configure Request Body` section.

<Thumbnail src="/img/actions/transform-body-disable.png" alt="Disable payload body" width="1100px" />

Hit `Save Action` to apply your changes.

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform][requesttransformation]
field to the action:

```yaml {8-9,13-16}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  request_transform:
    template_engine: Kriti
    version: 2
    method: GET
    url: '{{$base_url}}/create_user'
    query_params:
      id: '{{$session_variables[''x-hasura-user-id'']}}'
    body:
      action: 'remove'
    request_headers:
      remove_headers: ['content-type]
comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```http {26-27,32-37}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "request_transform": {
        "template_engine": "Kriti",
        "version": 2,
        "method": "GET",
        "url": "{{$base_url}}/create_user",
        "query_params": {
          "id": "{{$session_variables['x-hasura-user-id']}}"
        },
        "body": {
          "action": "remove"
        },
        "request_headers": {
          "remove_headers": ["content-type"],
        },
      }
    },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>

##### Request Body with application/json format

You can transform Request Body to `application/json` format using the following steps:

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Payload Transform`. By default, the Console sends the body as
`application/json` which can be seen in the dropdown next to the `Configure Request Body` section.

<Thumbnail src="/img/actions/transform-body-application-json.png" alt="payload body application/json" width="1100px" />

Hit `Save Action` to apply your changes.

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform][requesttransformation]
field to the action:

```yaml {8,13-15}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  request_transform:
    template_engine: Kriti
    version: 2
    method: POST
    url: '{{$base_url}}/create_user'
    query_params:
      id: '{{$session_variables[''x-hasura-user-id'']}}'
    body:
      action: 'transform'
      template: '{"username": {{$body.input.username}}}'
comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```http {26,32-35}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "request_transform": {
        "template_engine": "Kriti",
        "version": 2,
        "method": "POST",
        "url": "{{$base_url}}/create_user",
        "query_params": {
          "id": "{{$session_variables['x-hasura-user-id']}}"
        },
        "body": {
          "action": "transform"
          "template": "{\"username\": {{$body.input.username}}}"
        },
      }
    },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>

##### Request Body with x_www_form_urlencoded format

While doing `x_www_form_urlencoded` transformation, please note that as all changes to the request must be made explicit
when calling the API, so you will need to remove the default `application/json` header and add a
`application/x-www-form-urlencoded` header.

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Payload Transform`. Change the dropdown next to
`Configure Request Body` section to `x_www_form_urlencoded`. You can see the body transformed body in the
`Transformed Request Body` section.

<Thumbnail
  src="/img/actions/transform-body-xurl-formencoded.png"
  alt="payload body x_www_form_urlencoded"
  width="1100px"
/>

Hit `Save Action` to apply your changes.

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [request_transform][requesttransformation]
field to the action:

```yaml {8,13-20}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  request_transform:
    template_engine: Kriti
    version: 2
    method: POST
    url: '{{$base_url}}/create_user'
    query_params:
      id: '{{$session_variables[''x-hasura-user-id'']}}'
    body:
      action: 'x_www_form_urlencoded'
      form_template:
        username: '{{$body.input.username}}'
    request_headers:
      remove_headers: ['content-type']
      add_headers:
        'content-type': 'application/x-www-form-urlencoded'

comment: Custom action to create user
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [request_transform][requesttransformation] field to
the args:

```http {26,32-43}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "request_transform": {
        "template_engine": "Kriti",
        "version": 2,
        "method": "POST",
        "url": "{{$base_url}}/create_user",
        "query_params": {
          "id": "{{$session_variables['x-hasura-user-id']}}"
        },
        "body": {
          "action": "x_www_form_urlencoded",
          "form_template": {
            "username": "{{$body.input.username}}"
          },
        },
        "request_headers": {
          "remove_headers": ["content-type"],
          "add_headers": {
            "content-type": "application/x-www-form-urlencoded"
          },
        },
      }
    },
    "comment": "Custom action to create user"
  }
}
```

</TabItem>
</Tabs>

### Response Body

You can transform the default body of your HTTP API response by configuring a response transform template. This can be
used to match the output types defined in your Action with your HTTP API.

:::info Note

Response transforms are applicable only for JSON responses.

:::

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

In the `Configure REST Connectors` section, click on `Add Response Transform`:

<Thumbnail src="/img/actions/transform-response_actions_2.13.png" alt="response transform method" width="800px" />

Hit `Create Action` to apply your changes.

</TabItem>
<TabItem value="cli" label="CLI">

Update the `actions.yaml` file inside the `metadata` directory and add a [response_transform][responsetransformation]
field to the Action:

```yaml {6-9}
- name: create_user
  definition:
    kind: synchronous
    handler: https://action.my_app.com/create-user
  timeout: 60
  response_transform:
    template_engine: Kriti
    version: 2
    body: '{"action": "transform", "template": "{\n  \"test\":{{$body.input.arg1.id}}\n}"}'
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

REST Connectors can be configured for Actions using the [create_action][metadata-create-action] or
[update_action][metadata-update-action] Metadata APIs by adding a [response_transform][responsetransformation] field to
the args:

```http {24-29}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type":"create_action",
  "args":{
    "name":"create_user",
    "definition":{
      "kind":"synchronous",
      "arguments":[
        {
          "name":"username",
          "type":"String!"
        },
        {
          "name":"email",
          "type":"String!"
        }
      ],
      "output_type":"User",
      "handler":"{{ACTION_BASE_URL}}",
      "timeout":60,
      "response_transform": {
        "template_engine": "Kriti",
        "version": 2,
        "body": {"action": "transform", "template": "{\n  \"test\":{{$body.input.arg1.id}}\n}"},
        "comment": "Custom action to create user"
      }
    }
  }
}
```

</TabItem>
</Tabs>

:::info Note

You can also apply multiple transforms based on the following:

1. HTTP response received from the Action webhook in the response transform template. For example:

```
{{ if $response.status == 200 }}
  {
    "users": {
      "name": {{$body}},
      "password": {{$body}}
    }
  }
{{ elif $response.status == 400 }}
  {
    "message": {{$body.error}}
  }
{{ else }}
  {
    "message" : "internal error"
  }
{{ end }}
```

2. Session Variables. For example:

```
{{ if $session_variables["x-hasura-role"] == "admin" }}
  {
    "users": {
      "name": {{$body}},
      "password": {{$body}}
    }
  }
{{ elif $session_variables["x-hasura-role"] == "user" }}
  {
    "users": {
      "name": {{$body.username}},
      "password": "<redacted password>"
    }
  }
{{ else }}
  {
    "message" : "internal error"
  }
{{ end }}
```
:::

## Example

Let's integrate Auth0's management API to update the profile of a user:

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

Go to the `Actions` tab on the Console and create or modify an action. Scroll down to `Configure REST Connectors`
section:

Action definition:

<Thumbnail src="/img/actions/example-transformation-0.png" alt="Example rest connector for actions" width="1100px" />

The transformation is given by:

<Thumbnail src="/img/actions/example-transformation-1.png" alt="Example rest connector for actions" width="800px" />

<Thumbnail src="/img/actions/example-transformation-2.png" alt="Example rest connector for actions" width="1000px" />

</TabItem>
<TabItem value="cli" label="CLI">

To be added

</TabItem>
<TabItem value="api" label="API">

Action definition:

```graphql
type Mutation {
  updateProfile(picture_url: String!): ProfileOutput
}

type ProfileOutput {
  id: String!
  user_metadata: String!
}
```

The transform is given by:

```json
{
  "request_transform": {
    "body": "{\"user_metadata\": {\"picture\": {{$body.input.picture_url}} } }",
    "url": "{{$base_url}}/{{$session_variables['x-hasura-user-id']}}",
    "method": "PATCH"
  }
}
```

</TabItem>
</Tabs>

<!-- Shared Link Variables -->

[metadata-create-action]: /api-reference/metadata-api/actions.mdx#metadata-create-action
[metadata-update-action]: /api-reference/metadata-api/actions.mdx#metadata-update-action
[requesttransformation]: /api-reference/syntax-defs.mdx#requesttransformation
[responsetransformation]: /api-reference/syntax-defs.mdx#responsetransformation
